package ch.fhnw.qualiscan.application.views;

import ch.fhnw.qualiscan.Config;
import ch.fhnw.qualiscan.application.controllers.AdminPanel;
import ch.fhnw.qualiscan.application.modals.AddQuestionnaire;
import ch.fhnw.qualiscan.application.modals.AdminAddUniversity;
import ch.fhnw.qualiscan.application.modals.AdminEditRole;
import ch.fhnw.qualiscan.application.modals.AdminEditUniversity;
import ch.fhnw.qualiscan.application.modals.AdminEditUser;
import ch.fhnw.qualiscan.application.modals.AdminNewRole;
import ch.fhnw.qualiscan.application.modals.DeleteQuestionnaire;
import ch.fhnw.qualiscan.core.View;
import ch.fhnw.qualiscan.core.db.helpers.AdminParticipantTableArgs;
import ch.fhnw.qualiscan.core.db.helpers.adminRoleTableArgs;
import ch.fhnw.qualiscan.core.db.pojos.Questionnaire;
import ch.fhnw.qualiscan.core.db.pojos.Stage;
import ch.fhnw.qualiscan.core.db.pojos.Survey;
import ch.fhnw.qualiscan.core.db.pojos.University;
import ch.fhnw.qualiscan.core.db.pojos.User;
import ch.fhnw.qualiscan.core.libraries.NotificationLibrary;
import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import eu.livotov.tpt.TPTApplication;
import eu.livotov.tpt.gui.dialogs.OptionDialog;
import eu.livotov.tpt.gui.dialogs.OptionKind;
import eu.livotov.tpt.i18n.TM;

/**
 *
 * @author bengro
 */
public class AdminPanelView extends View {
    
    private AdminPanelView adminView;
    private AdminPanel adminController;
    private VerticalLayout adminWrap;
    private Label title;
    
    VerticalLayout editQuestionnaireTab;
    VerticalLayout editUsersTab;
    VerticalLayout editSurveysTab;
    VerticalLayout editRolesTab;
    VerticalLayout editUnisTab;
    
    Table roleTable;
    Table universityTable;
    Table usersTable;
    Table questionnaireTable;
    
    public AdminPanelView(AdminPanel adminController) {
        this.adminController = adminController;
        this.adminView = this;
    }

    @Override
    public void initComponents() {
        
    }

    /**
     * Builds the main layout.
     */
    @Override
    public void buildLayout() {
    	
    	tabSheet.removeAllComponents();
    	removeAllComponents();
    	
        adminWrap = new VerticalLayout();
	adminWrap.setMargin(true, true, true, true);
	adminWrap.setSpacing(true);
		
	title = textHelper.h1(TM.get("admin.title"));
	adminWrap.addComponent(title);
		
	addComponent(adminWrap);
        
        tabSheet = new TabSheet();
        
        // TODO: add proper i18n tags.
        tabSheet.addTab(editQuestionnaireTab(), TM.get("admin.tab1.title"), null);
	tabSheet.addTab(editUsers(), TM.get("admin.tab2.title"), null);
        tabSheet.addTab(editSurveys(), TM.get("admin.tab3.title"), null);
        tabSheet.addTab(editRoles(), TM.get("admin.tab4.title"), null);
        tabSheet.addTab(editUnis(), TM.get("admin.tab5.title"), null);
        
        addComponent(tabSheet);
    }
    
    /**
     * Responsible for the tab handling the questionnaires.
     * @return 
     */
    private VerticalLayout editQuestionnaireTab() {
        editQuestionnaireTab = new VerticalLayout();
        editQuestionnaireTab.setMargin(true);
        
        HorizontalLayout addDomainForm = new HorizontalLayout();
	addDomainForm.setMargin(true, true, true, false);
	Button addButton =  new Button(TM.get("action.add"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                openModal(new AddQuestionnaire(adminView, null));
            }
        });
        
        addButton.setIcon(Config.ICON_ADD);
	addDomainForm.addComponent(addButton);
	editQuestionnaireTab.addComponent(addDomainForm);
        
        
    questionnaireTable = new Table();
    questionnaireTable.setWidth("100%");
	questionnaireTable.setPageLength(0);
	questionnaireTable.setSelectable(true);
    questionnaireTable.setImmediate(true);
        
        // generate buttons
    questionnaireTable.addGeneratedColumn("gen_edit", new Table.ColumnGenerator() {
                public Component generateCell(Table source, Object itemId, Object columnId) {
                        final Questionnaire thisQuestionnaire = (Questionnaire) source.getContainerProperty(itemId, "questionnaire").getValue();
                        Button b = new Button(TM.get("action.edit"));
                        b.setData(thisQuestionnaire.getId());
                        
                        b.addListener(new Button.ClickListener() {
                            
                            public void buttonClick(ClickEvent event) {
                                int selectedQuestionnaireId = thisQuestionnaire.getId();
                                Questionnaire selectedQuestionnaire = adminController.getqModel().getQuestionnaire(selectedQuestionnaireId);
                                if(selectedQuestionnaire != null) {
                                    adminController.loadQuestionnairePage(selectedQuestionnaire);
                                } else {
                                    System.out.append("error... selectedQuestionnaireId: " + selectedQuestionnaireId);
                                }
                            }
                        });	
                        b.setIcon(Config.ICON_EDIT);
                        return b;
                }
        });

        questionnaireTable.addGeneratedColumn("gen_delete", new Table.ColumnGenerator() {
                public Component generateCell(Table source, final Object itemId, Object columnId) {
                        final Questionnaire thisQuestionnaire = (Questionnaire) source.getContainerProperty(itemId, "questionnaire").getValue();
                        Button b = new Button(TM.get("action.delete"));
                        b.setData(thisQuestionnaire.getId());
                        
                        b.addListener(new Button.ClickListener() {
                            public void buttonClick(ClickEvent event) {
                                
                                Questionnaire selectedQuestionnaire = adminController.getqModel().getQuestionnaire(thisQuestionnaire.getId());
                                if(selectedQuestionnaire != null) {
                                    openModal(new DeleteQuestionnaire(selectedQuestionnaire, adminView));
                                } else {
                                    System.out.append("error... selectedQuestionnaireId: " + thisQuestionnaire.getId());
                                }
                            }
                        });	
                        b.setIcon(Config.ICON_DELETE);
                        return b;
                }
        });
        
        questionnaireTable.setContainerDataSource(adminController.getQuestionaireData());

        questionnaireTable.setColumnHeader("title", TM.get("questionnaire.title"));
        questionnaireTable.setColumnHeader("desc", TM.get("questionnaire.desc"));
        questionnaireTable.setColumnHeader("createdAt", TM.get("questionnaire.created"));
        questionnaireTable.setColumnHeader("gen_edit", TM.get("action.edit"));
        questionnaireTable.setColumnHeader("gen_delete", TM.get("action.delete"));

        questionnaireTable.setVisibleColumns(
            new Object[]{
                "title", 
                "desc", 
                "createdAt", 
                "gen_edit", 
                "gen_delete"
            }
        );
        
     
        editQuestionnaireTab.addComponent(questionnaireTable);
        return editQuestionnaireTab;
    }

    /**
     * Shows a list of users which can be edited.
     * @return 
     */
    private VerticalLayout editUsers() {
        editUsersTab = new VerticalLayout();
        editUsersTab.setMargin(true);
        
        final BeanItemContainer<AdminParticipantTableArgs> tableContainer = adminController.getUserTableData();
        
        usersTable = new Table();
	usersTable.setWidth("100%");
	usersTable.setPageLength(10);
	usersTable.setSelectable(true);
        usersTable.setImmediate(true);
        
        // generate buttons
        usersTable.addGeneratedColumn("gen_edit", new Table.ColumnGenerator() {
                public Component generateCell(Table source, Object itemId, Object columnId) {
                        final User thisUser = (User) source.getContainerProperty(itemId, "user").getValue();
                        Button b = new Button(TM.get("action.edit"));
                        b.setData(thisUser.getId());
                        b.addListener(new Button.ClickListener() {
                                public void buttonClick(Button.ClickEvent event) {
                                    openModal(new AdminEditUser(thisUser.getId(), adminView));
                                }
                        });	
                        b.setIcon(Config.ICON_EDIT);
                        return b;
                }
        });

        usersTable.addGeneratedColumn("gen_delete", new Table.ColumnGenerator() {
                public Component generateCell(Table source, final Object itemId, Object columnId) {
                        final User thisUser = (User) source.getContainerProperty(itemId, "user").getValue();
                        Button b = new Button(TM.get("action.delete"));
                        b.setData(thisUser.getId());
                        b.addListener(new Button.ClickListener() {
                                public void buttonClick(Button.ClickEvent event) {

                                        final OptionDialog dlg = new OptionDialog (TPTApplication.getCurrentApplication ());
                                        final String name;
                                        if(thisUser.getFirstname().equals("")) {
                                                name = thisUser.getEmail();
                                        } else {
                                                name = thisUser.getFirstname() + " " + thisUser.getLastname();
                                        }
                                        dlg.showConfirmationDialog(TM.get("admin.tab3.userdelete"), TM.get("admin.tab3.userdelete.desc", name), new OptionDialog.OptionDialogResultListener () {
                                          public void dialogClosed(OptionKind closeEvent) {
                                                  if(closeEvent == OptionKind.OK) {
                                                          NotificationLibrary.showSuccess(name + " " + TM.get("action.deleted"), null);
                                                          tableContainer.removeItem(itemId);
                                                          adminController.getAdminModel().deleteUser(thisUser);
                                                          updateUsers();
                                                  }
                                          }
                                        });

                                }
                        });	
                        b.setIcon(Config.ICON_DELETE);
                        return b;
                }
        });

        usersTable.setContainerDataSource(adminController.getUserTableData());

        usersTable.setColumnHeader("firstname", TM.get("user.firstname"));
        usersTable.setColumnHeader("lastname", TM.get("user.lastname"));
        usersTable.setColumnHeader("email", TM.get("user.email"));
        usersTable.setColumnHeader("role", TM.get("user.role"));
        usersTable.setColumnHeader("language", TM.get("user.language"));
        usersTable.setColumnHeader("gen_edit", TM.get("action.edit"));
        usersTable.setColumnHeader("gen_delete", TM.get("action.delete"));

        usersTable.setVisibleColumns(
            new Object[]{
                "firstname", 
                "lastname", 
                "email", 
                "language", 
                "gen_edit", 
                "gen_delete"
            }
        );
        
        editUsersTab.addComponent(usersTable);
        
        return editUsersTab;
    }
    
    
    public void updateUsers() {
        usersTable.setContainerDataSource(adminController.getUserTableData());
        usersTable.setVisibleColumns(
            new Object[]{
                "firstname", 
                "lastname", 
                "email", 
                "language", 
                "gen_edit", 
                "gen_delete"
            }
        );
    }
    
    /**
     * shows a list of all surveys - they can be deleted.
     * @return 
     */
    private VerticalLayout editSurveys() {
        editSurveysTab = new VerticalLayout();
        editSurveysTab.setMargin(true);
        
        final BeanItemContainer<Survey> tableContainer = adminController.getSurveyTableData();
        
        Table surveyTable = new Table();
        surveyTable.setWidth("100%");
        surveyTable.setPageLength(0);
        surveyTable.setSelectable(true);

        surveyTable.addGeneratedColumn("stageTitle", new Table.ColumnGenerator() {
                public Component generateCell(Table source, Object itemId, Object columnId) {
                        Survey survey = (Survey) itemId;
                        Stage stage = survey.getStage();

                        Label stageTitle = new Label(adminController.getSurveyModel().getStageText(stage, adminController.userSession.getLanguage()).getTitle());
                        return stageTitle;
                }
        });

        surveyTable.addGeneratedColumn("surveyDeleteButton", new Table.ColumnGenerator() {
                public Component generateCell(Table source, final Object itemId, Object columnId) {
                        Button deleteButton = new Button(TM.get("action.delete"), new Button.ClickListener() {
                                public void buttonClick(Button.ClickEvent event) {
                                        final OptionDialog dlg = new OptionDialog (TPTApplication.getCurrentApplication ());
                                        dlg.showConfirmationDialog(TM.get("admin.tab4.surveydelete"), TM.get("admin.tab4.surveydelete.desc", ((Survey) itemId).getTitle()), new OptionDialog.OptionDialogResultListener () {
                                          public void dialogClosed(OptionKind closeEvent) {
                                                  if(closeEvent == OptionKind.OK) {
                                                          NotificationLibrary.showSuccess(((Survey)itemId).getTitle() + " " + TM.get("action.deleted"), null);
                                                          tableContainer.removeItem(itemId);
                                                          adminController.getAdminModel().deleteSurvey((Survey) itemId);
                                                  }
                                          }
                                        });
                                }
                        });
                        deleteButton.setData(itemId);
                        deleteButton.setIcon(Config.ICON_CANCEL);

                        return deleteButton;
                }
        });

        surveyTable.setContainerDataSource(tableContainer);

        surveyTable.setColumnHeader("title", TM.get("admin.surveytable.title"));
        surveyTable.setColumnHeader("stageTitle", TM.get("admin.surveytable.stage"));
        surveyTable.setColumnHeader("creationdate", TM.get("admin.surveytable.creationdate"));
        surveyTable.setColumnHeader("completiondate", TM.get("admin.surveytable.completiondate"));
        surveyTable.setColumnHeader("surveyDeleteButton", TM.get("action.delete"));

        surveyTable.setVisibleColumns(new Object[]{"title", "stageTitle", "creationdate", "completiondate", "surveyDeleteButton"});
		
	editSurveysTab.addComponent(surveyTable);	
        
        return editSurveysTab;
    }
    
    /**
     * Shows all existing roles of the system.
     * @return 
     */
    private VerticalLayout editRoles() {
        editRolesTab = new VerticalLayout();
        editRolesTab.setMargin(true);
        
        // load data
        final BeanItemContainer<adminRoleTableArgs> tableContainer = adminController.getRolesTableData();
        
        // add form
        HorizontalLayout addDomainForm = new HorizontalLayout();
	addDomainForm.setMargin(true, true, true, false);
		
	Button addButton =  new Button(TM.get("action.add"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                openModal(new AdminNewRole(tableContainer, adminView));
            }
        });
	addButton.setIcon(Config.ICON_ADD);
	addDomainForm.addComponent(addButton);
	editRolesTab.addComponent(addDomainForm);	
        
	
        // roles table
        roleTable = new Table();
	roleTable.setWidth("100%");
	roleTable.setPageLength(0);
	roleTable.setSelectable(true);
	
	roleTable.addGeneratedColumn("roleEditButton", new Table.ColumnGenerator() {
            public Component generateCell(Table source, Object itemId, Object columnId) {
 		Button editButton = new Button(TM.get("action.edit"), new Button.ClickListener() {
                    public void buttonClick(Button.ClickEvent event) {
                        adminRoleTableArgs arta = (adminRoleTableArgs) event.getButton().getData();
                        openModal(new AdminEditRole(arta, adminView));
                    }
		});
                
                editButton.setData(itemId);
		editButton.setIcon(Config.ICON_EDIT);
		return editButton;
            }
	});
		
	roleTable.setContainerDataSource(tableContainer);
		
	roleTable.setColumnHeader("titleEng", TM.get("admin.roletable.engtitle"));
	roleTable.setColumnHeader("permission", TM.get("admin.roletable.permission"));
	roleTable.setVisibleColumns(new Object[]{"titleEng", "permission", "roleEditButton"});
		
        editRolesTab.addComponent(roleTable);
        
        return editRolesTab;
    }
    
    public void updateRoles() {
        roleTable.setContainerDataSource(adminController.getRolesTableData());
        roleTable.setColumnHeader("titleEng", TM.get("admin.roletable.engtitle"));
	roleTable.setColumnHeader("permission", TM.get("admin.roletable.permission"));
	roleTable.setVisibleColumns(new Object[]{"titleEng", "permission", "roleEditButton"});
    }
    
    /**
     * shows a list of all universities.
     * @return 
     */
    private VerticalLayout editUnis() {
        editUnisTab = new VerticalLayout();
        editUnisTab.setMargin(true);
        
        // add form
        HorizontalLayout addDomainForm = new HorizontalLayout();
	addDomainForm.setMargin(true, true, true, false);
		
	Button addButton =  new Button(TM.get("action.add"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                openModal(new AdminAddUniversity(adminView));
            }
        });
        
        addButton.setIcon(Config.ICON_ADD);
	addDomainForm.addComponent(addButton);
	editUnisTab.addComponent(addDomainForm);
        
        // add table
        BeanItemContainer<University> tableContainer = adminController.getUniversitiesTableData();
        
        universityTable = new Table();
	universityTable.setWidth("100%");
	universityTable.setPageLength(0);
	universityTable.setSelectable(true);
		
	universityTable.addGeneratedColumn("universityEditButton", new Table.ColumnGenerator() {
	public Component generateCell(Table source, Object itemId, Object columnId) {
            Button editButton = new Button(TM.get("action.edit"), new Button.ClickListener() {
                public void buttonClick(Button.ClickEvent event) {
                    University university = (University) event.getButton().getData();
                    openModal(new AdminEditUniversity(university, adminView));
		}
            });
 	
            editButton.setData(itemId);
            editButton.setIcon(Config.ICON_EDIT);
                return editButton;
            }
	});
		
	universityTable.setContainerDataSource(tableContainer);
		
	universityTable.setColumnHeader("title", TM.get("admin.universitytable.title"));
	universityTable.setColumnHeader("universityEditButton", TM.get("admin.edituniversity.title"));
	universityTable.setVisibleColumns(new Object[]{"title", "universityEditButton"});
    
        editUnisTab.addComponent(universityTable);
        
        return editUnisTab;
    }

    public void updateUnis() {
        universityTable.setContainerDataSource(adminController.getUniversitiesTableData());
        universityTable.setColumnHeader("title", TM.get("admin.universitytable.title"));
	universityTable.setColumnHeader("universityEditButton", TM.get("admin.edituniversity.title"));
	universityTable.setVisibleColumns(new Object[]{"title", "universityEditButton"});
    }

 

	@Override
	public void reBuild() {
		questionnaireTable.setContainerDataSource(adminController.getQuestionaireData()); 
        questionnaireTable.setColumnHeader("title", TM.get("questionnaire.title"));
        questionnaireTable.setColumnHeader("desc", TM.get("questionnaire.desc"));
        questionnaireTable.setColumnHeader("createdAt", TM.get("questionnaire.created"));
        questionnaireTable.setColumnHeader("gen_edit", TM.get("action.edit"));
        questionnaireTable.setColumnHeader("gen_delete", TM.get("action.delete"));

        questionnaireTable.setVisibleColumns(
            new Object[]{
                "title", 
                "desc", 
                "createdAt", 
                "gen_edit", 
                "gen_delete"
            }
        );
		
	}

}
